#ifndef TLISTAPORO_H_
#define TLISTAPORO_H_

#include "tporo.h"

/** \file tlistaporo.h
* \brief Clases de la lista
* Definiciones de las clases
*/

/** \class TListaPoro
* \brief Defincion forward
* Definicion forward de la clase TListaPoro
*/
class TListaPoro;

/** \class TListaNodo
* \brief Clase TListaNodo
* Clase completa para construir TListaNodo
*/
class TListaNodo
{

	friend class TListaPosicion;
	friend class TListaPoro;
        
	/** \brief Sobrecarga del operador salida.
	* Imprime por pantalla el objeto TListaPoro.
	* \param os objeto de salida.
	* \param l tipo TListaPoro.
         * \return ostream&
	*/
	friend ostream & operator<<(ostream &os, const TListaPoro &lp);
	private:
                        /** \brief Objeto Poro.
                        *   Un nodo consiste de un objeto poro
                        */
			TPoro e;

                        /** \brief Puntero al anterior.
                        *   Puntero al anterior nodo
                        */
                        TListaNodo* anterior;
                        
                        /** \brief Puntero al siguiente.
                        *   Puntero al siguiente nodo
                        */
                        TListaNodo* siguiente;
	public:
                        /** \brief Constructor por defecto.
                	* Construye el objeto TListaNodo.
                        */
                        TListaNodo();

                        /** \brief Constructor de copia.
                	* Construye el objeto TListaNodo apartir de otro.
                         * \param nodo Nodo a copiar
                        */
			TListaNodo(const TListaNodo &);
                        
                        /** \brief Destructor TListaNodo.
                	* Destruye el objeto TListaNodo.
                        */
                        ~TListaNodo();
                        
                	/** \brief Sobrecarga del operador asignacion.
                	* Sobrecarga el operador igual de asignacion para dos objetos TVectorPoro.
                	* \param nodo objeto del cual copiar.
                	*/
                        TListaNodo & operator=(const TListaNodo &);
};

/** \class TListaPosicion
* \brief Clase TListaPosicion
* Clase completa para construir TListaPosicion
*/
class TListaPosicion
{
	friend class TListaPoro;
	friend class TPilaPoro;
	friend class TListaNodo;

	/** \brief Sobrecarga del operador salida.
	* Imprime por pantalla el objeto TListaPosicion.
	* \param os objeto de salida.
	* \param l tipo TListaPosicion.
         * \return ostream&
	*/
	friend ostream & operator<<(ostream &os, const TListaPoro &lp);
	private:
			/** \brief Punteros que representan a TListaPosicion.
			 * Puntero *pos tipo TListaNodo;
			 */
			TListaNodo *pos;
	public:
			/** \brief Constructor.
			* Construye el objeto TListaPosicion.
			*/
			TListaPosicion();

			/** \brief Constructor de copia.
			* Crea una copia del objeto que recibe.
			* \param p, objeto tipo TListaPosicion que recibe.
			*/
			TListaPosicion(const TListaPosicion &p);

			/** \brief Destructor.
			* Destruye el objetos.
			*/
			~TListaPosicion();

			/** \brief Sobrecarga del operador asignación.
			* Copia los valores de un objeto a otro.
			* \param lp tipo TListaPosicion;
			* \return TListaPosicion, devuelte un objeto de tipo TListaPosicion.
			*/
			TListaPosicion &operator=(const TListaPosicion &lp);

			/** \brief Sobrecarga del operador igualdad.
			* Compara los dos listas y devuelve si son o no son iguales.
			* \param lp objeto de tipo TListaPosicion.
			* \return devuelve si las dos listas comparadas son o no son iguales.
			*/
			bool operator==(const TListaPosicion &lp) const;

			/** \brief Devuelve la posicion anterior.
			* Devuelve la posicion anterior de la lista.
			* \return devuelve la posicion anterior.
			*/
			TListaPosicion Anterior();

			/** \brief Devuelve la posicion siguiente.
			* Devuelve la posicion siguiente de la lista.
			* \return devuelve la posicion siguiente.
			*/
			TListaPosicion Siguiente();

			/** \brief Devuelve TRUE si la posicion no apunta a una lista, FALSE en caso contrario.
			* Devuelve TRUE si la posicion no apunta a una lista, FALSE en caso contrario.
			* \return devuelve si la posicion apunta o no a una lista.
			*/
			bool EsVacia();
};

/** \class TListaPoro
* \brief Clase TListaPoro
* Clase completa para construir TListaPoro
*/
class TListaPoro
{

	friend class TPoro;
	friend class TListaNodo;
	friend class TListaPosicion;
        
	/** \brief Sobrecarga del operador salida.
	* Imprime por pantalla el objeto TListaPoro.
	* \param os objeto de salida.
	* \param lp tipo TListaPoro.
	*/
	friend ostream & operator<<(ostream &os, const TListaPoro &lp);

	private:
			/** \brief Puntero primero.
                        * Puntero *primero tipo TListaNodo.
                        */
			TListaNodo *primero;
			/** \brief Puntero ultimo.
                        * Puntero *ultimo tipo TListaNodo.
                        */
                        TListaNodo *ultimo;
	public:
			/** \brief Constructor.
			* Construye el objeto TListaPoro.
			*/
			TListaPoro();

			/** \brief Constructor de copia.
			* Crea una copia del objeto que recibe.
			* \param p objeto tipo TPilaPoro que recibe.
			*/
			TListaPoro(const TListaPoro &p);

			/** \brief Destructor.
			* Destruye el objetos.
			*/
			~TListaPoro();

			/** \brief Sobrecarga del operador asignación.
			* Copia los valores de un objeto a otro.
			* \param lp tipo TListaPoro;
			* \return TListaPoro, devuelte un objeto de tipo TListaPoro.
			*/
			TListaPoro &operator=(const TListaPoro &lp);

			/** \brief Sobrecarga del operador igualdad.
			* Compara los dos listas y devuelve si son o no son iguales.
			* \param lp objeto de tipo TListaPoro.
			* \return bool, devuelve si las dos listas comparadas son o no son iguales.
			*/
			bool operator==(const TListaPoro &lp) const;

			/** \brief Sobrecarga del operador suma.
			* Une los elementos de dos listas en una nueva lista(ordenada y sin repetidos).
			* \param lp objeto de tipo TListaPoro.
			* \return TListaPoro, devuelve un objeto de tipo TListaPoro.
			*/
			TListaPoro operator+(const TListaPoro &lp)const;

			/** \brief Sobrecarga del operador resta.
			* Devuelve una lista nueva que contiene los elementos de la primera lista que no existen en la segunda lista.
			* \param lp objeto de tipo TListaPoro.
			* \return TListaPoro, devuelve un objeto de tipo TListaPoro.
			*/
			TListaPoro operator-(const TListaPoro &lp) const;

			/** \brief Comprueba si la lista esta vacia.
			* Comprueba si la lista esta vacia.
			* \return bool, devuelve verdadero si la lista esta vacia, false en caso contrario.
			*/
			bool EsVacia();

			/** \brief Inserta en la posicion adecuada.
			* El nuevo elemento se inserta en la posicion adecuada para que siga siendo una lista ordenada.
			* \param p objeto de tipo TPoro.
			* \return bool, devuelve si se ha o no se ha insertado el poro en la lista.
			*/
			bool Insertar(const TPoro &p);

			/** \brief Comprueba si un elemento se puede borrar de la lista.
			* Devuelve true si el elemento se puede borrar y false en caso contrario.
			* \param p objeto de tipo TPoro.
			* \return bool, devuelve si se puede borrar el elemento.
			*/
			bool Borrar(const TPoro &p);

			/** \brief Borra elementos de la lista.
			* Borra elementos de la lista.
			* \param lp objeto de tipo TListaPoro.
			* \return bool, devuelve si se ha borrado o no el elemento.
			*/
			bool Borrar(TListaPosicion &lp);

			/** \brief Obtiene la posicion de la lista.
			* Obtiene la posicion.
			* \param lp objeto de tipo TListaPoro.
			* \return TPoro, devuelve un objeto de tipo TPoro.
			*/
			TPoro Obtener(const TListaPosicion &lp) const;

			/** \brief Realiza una busqueda.
			* Realiza una busqueda desde el primero hasta el ultimo elemento.
			* \param p objeto de tipo TPoro.
			* \return bool, devuelve si se ha encontrado el elemento.
			*/
			bool Buscar(const TPoro &p) const;

			/** \brief Devuelve el numero de elementos que existen en la lista.
			* Devuelve el numero de elementos que existen en la lista.
			* \return int, devuelve el numero de elemento.
			*/
			int Longitud() const;

			/** \brief Objeto de primera posicion.
			* Devuelve la primera posicion de la lista
                         * \return Objeto posicion primera.
			*/
			TListaPosicion Primera();

			/** \brief Objeto de ultima posicion.
			* Devuelve la ultima posicion de la lista.
                         * \return Objeto posicion ultima.
			*/
			TListaPosicion Ultima();

};

#endif /* TLISTAPORO_H_ */
